package com.mc.java8;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class FunctionInterfaceTest {
    @Test
    public void testFunction() {
        handle(2, x -> System.out.println(x + new Student().setAge(2).getAge()));
        Student supply = supply(() -> new Student());
        System.out.println(supply);
        Student student = new Student().setName("张三").setAge(12);

        Student student1 = stFunction(student, x -> {
              x.setName("lisi");
            return x.getName();
        });
        System.out.println(student1);

    }

    //消费型接口 Consumer<T>  void accept(T t);  接受一个输入参数并且无返回值

    @Test
    public void testConsumer() {
        handle(6, (x) -> System.out.println(x + 2));
    }
   

    public void handle(int a, Consumer<Integer> value) {
        value.accept(a);

    }

    //供给型接口 Supplier<T> T get(); 无输入参数，返回一个结果T
    public Student supply(Supplier<Student> st) {
        return st.get();

    }

    @Test
    public void testSupplier() {
        Student st = new Student().setName("abc");

        System.out.println(getObject(() -> st.getName()));
    }

    public String getObject(Supplier<String> supplier) {
        return supplier.get();
    }

    //函数型接口 Function<T,R>  R apply(T t);  接受一个输入参数T，返回一个结果R
    public Student stFunction(Student st, Function<Student, String> stFunction) {
        Student student = new Student();
        /*stFunction.apply(student);*/
        String apply = stFunction.apply(st);
        return st;
    }


    @Test
    public void testFunction1() {
        int result = plusTwo(6, (x) -> x + 2);
        System.out.println(result);

        int before = before(6, x -> x + 2, x -> x * 10);
        // 62
        System.out.println(before);

        int after = after(6, x -> x + 2, x -> x * 10);
        // 80
        System.out.println(after);
    }

    public Integer plusTwo(int origen, Function<Integer, Integer> function) {
        return function.apply(origen);
    }

    public Integer before(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        // value作为function2的参数，返回一个结果，该结果作为function1的参数，返回一个最终结果
        return function1.compose(function2).apply(value);
    }

    public Integer after(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        // value作为function1的参数，返回一个结果，该结果作为function2的参数，返回一个最终结果
        return function1.andThen(function2).apply(value);
    }

    //断言型接口  Predicate<T>  boolean test(T t);  接受一个输入参数T，返回一个布尔值结果。

    @Test
    public void testPredicate() {
        boolean judge = judge(6, (x) -> (x & 1) != 1);
        System.out.println(judge);

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        System.out.println("输出所有数据:");
        eval(list, x -> true);
        // 1 2 3 4 5 6 7 8 9
        System.out.println();
        System.out.println("输出所有偶数:");
        eval(list, x -> (x & 1) != 1);
        // 2 4 6 8
        System.out.println();
        System.out.println("输出大于 3 的所有数字:");
        eval(list, x -> x > 3);
        // 4 5 6 7 8 9
        System.out.println();

        // 验证输入是否正确
        boolean valid = valid("许宣", x -> !x.isEmpty() && x.length() <= 3);
        System.out.println(valid);
    }

    public boolean judge(Integer input, Predicate<Integer> predicate) {
        return predicate.test(input);
    }

    public static void eval(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {
            if (predicate.test(n)) {
                System.out.print(n + " ");
            }
        }
    }

    public boolean valid(String name, Predicate<String> predicate) {
        return predicate.test(name);
    }
}